/**
 * 
 */
package games;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Random;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;


/**
 * @author Owner
 *
 */
public class Centipede extends Game {
	/**
	 * 
	 */
	private static final long serialVersionUID=1L;
	
	private static final String DATA_FOLDER="games\\data\\";
	private static final String PLAYER_NAME="Player";
	private static final String DEFECTION_NAME="DefectionBonus";
	private static final String SUFFIX=".data";
	private static final String GAME_NAME="Centipede";
	private static final String PASS="Pass";
	private static final String DEFECT="Defect";
	private static final String FIRST_LINE="You are Player %d.";
	private static final String PASS_LINE=" Player %d passed.";
	private static final String SECOND_LINE="What would you like to do?";
	private static final String THIRD_LINE="You have";
	public static final Font FONT=new Font(Font.SERIF,Font.BOLD,60);
	
	int player;
	int endowment;
	int interval;
	int bonus;
	int turn;
	int maxTurn;
	String str;
	Vector<Vector<Move>> otherPlayer=new Vector<Vector<Move>>(100);
	FontMetrics fm=getFontMetrics(FONT);
	FontMetrics hfm=getFontMetrics(HEADER_FONT);
	NumberPainter painter=new NumberPainter();
	HeaderPainter headerPainter=new HeaderPainter();
	
	
	/**
	 * @param runner
	 * @param gameName
	 */
	public Centipede(Runner runner,int player,int endowment,int interval,int bonus,int turn) {
		super(runner,GAME_NAME);
		this.player=player;
		this.endowment=endowment;
		this.interval=interval;
		this.bonus=bonus;
		maxTurn=turn;
	}
	
	public Centipede(Runner runner) {
		this(runner,1,3,1,2,10);
	}

	public void init() {
		// Turn off metal's use of bold fonts
		UIManager.put("swing.boldMetal",Boolean.FALSE);
	}

	public void start() {
		initComponents();
	}
	
	public void initComponents() {
		setLayout(new BorderLayout());
		
		turn=0;
		getOtherPlayer();

		main=new JPanel(new BorderLayout());
		header=new JPanel(new BorderLayout());
		footer=new JPanel(new BorderLayout());
		
		headerPainter=new HeaderPainter();
		header.add(headerPainter);
		main.add(BorderLayout.NORTH,header);
		painter=new NumberPainter();
		
		main.add(BorderLayout.CENTER,painter);
		add(BorderLayout.CENTER,main);
		
		go=new Painter("go","Click to Pass");
		stop=new Painter("stop","Click to Accept");
		
		footer.add(BorderLayout.EAST,go);
		footer.add(BorderLayout.WEST,stop);
		add(BorderLayout.SOUTH,footer);
		
		
		clock=new Timing();
		getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"),"selector");
		getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("G"),"changer");
		
		getActionMap().put("selector",new AbstractAction() {
			/**
			 * 
			 */
			private static final long serialVersionUID=1L;

			public void actionPerformed(ActionEvent e) {
				//System.err.println("Selector pushed");
				suspend();
				time=clock.getElapsedTime();
				log(DEFECT,endowment);
				finished(GAME_NAME,time);
			}
		});		
		getActionMap().put("changer",new AbstractAction() {
			/**
			 * 
			 */
			private static final long serialVersionUID=1L;

			public void actionPerformed(ActionEvent e) {
				//System.err.println("Changer pushed");
	      	suspend();
	      	time=clock.getElapsedTime();
					log(PASS,time);
					if(player==2) turn++;
					getMove();
					if(player==1) turn++;
					proceed();
			}
		});
		
    proceed();
	}

	public void getMove() {
		Vector<Move> possibilities=otherPlayer.get(turn);
		Random random=new Random();
		Move move=possibilities.get(random.nextInt(possibilities.size()));
		log(move.toString());
		
		System.out.println(possibilities);
		System.out.println(turn);
		
		if(move.pass) {
			endowment+=interval*2;
			repaint();
		}
		else {
			finished(GAME_NAME,time);
		}
	}
	
	public void getOtherPlayer() {
		try {
			//CentipedePlayer23.01.0DefectionBonus2.data
			File f=new File(DATA_FOLDER+GAME_NAME+PLAYER_NAME+(player%2+1)+
					(float)endowment+(float)interval+DEFECTION_NAME+bonus+SUFFIX);
			//System.out.println(f.exists());			
			BufferedReader r=new BufferedReader(new FileReader(f));
			//System.out.println(r.readLine());
			
			String[] tokens;
			int turns;
			String current;
			
			while((current=r.readLine())!=null) {
				tokens=current.split("\t");
				turns=Integer.parseInt(tokens[1].replaceAll(PASS,"").replaceAll(DEFECT,""));
				
				//create the necessary inner arrays
				for(int i=otherPlayer.size();i<turns;i++) {
					//System.out.println(i);
					otherPlayer.add(new Vector<Move>());
				}
				
				//add the turns
				for(int i=0;i<turns-1;i++) {
					otherPlayer.get(i).add(new Move(tokens[0],true));
				}
				otherPlayer.get(turns-1).add(new Move(tokens[0],tokens[1].startsWith(PASS)));
				
			}
			//for(Vector<Move>v:otherPlayer) for(Move m:v) System.out.println(m);
			//System.out.println(otherPlayer);
			
			
		} catch(FileNotFoundException e) {
			System.err.println("Can't find the file.");
			e.printStackTrace();
		} catch(IOException e) {
			System.err.println("Problem reading the file.");
			e.printStackTrace();
		}
	}
	
	class Move {
		String id;
		boolean pass;
		
		public Move(String id,boolean pass) {
			this.id=id;
			this.pass=pass;
		}
		
		public String toString() {
			return id+"\t"+(pass?PASS:DEFECT);
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame f=new JFrame();
		f.setLayout(new BorderLayout());
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Centipede ap=new Centipede(new Runner());
		ap.init();
		ap.start();
		f.add("Center",ap);
		f.pack();
		f.setVisible(true);
		f.setSize(600,500);
	}

	
	class HeaderPainter extends Component {
		/**
		 * 
		 */
		private static final long serialVersionUID=1L;
		
	  public Dimension getPreferredSize(){
	    return new Dimension(WIDTH,100);
		}
	  
	  public void paint(Graphics g) {
	    int cWidth=getWidth();
	    g.setFont(HEADER_FONT);
	    
	    //draw the header
	    String s=String.format(FIRST_LINE,player);
	    if(turn!=0 || player!=1) s+=String.format(PASS_LINE,player%2+1);
	    int width=(hfm.stringWidth(s));
	    g.drawString(s,(cWidth-width)/2,25);
	    width=(hfm.stringWidth(SECOND_LINE));
	    g.drawString(SECOND_LINE,(cWidth-width)/2,50);
	    width=(hfm.stringWidth(THIRD_LINE));
	    g.drawString(THIRD_LINE,(cWidth-width)/2,75);
	    
		}
	}
	
	class NumberPainter extends Component {
		/**
		 * 
		 */
		private static final long serialVersionUID=1L;
		
	  public Dimension getPreferredSize(){
	    return new Dimension(600,100);//-headerPainter.getHeight());
		}
	  
	  public void paint(Graphics g) {
	    //Dimension size = getSize();
	    int cWidth=getWidth();
	    
	    //draw the number
			str="$"+Integer.toString(endowment);
	    int width=fm.stringWidth(str);
	    g.setFont(FONT);
	    g.drawString(str,(cWidth-width)/2,100);
		}
	}
}
